<style scoped lang="scss">
.base-charts {
  position: relative;
  width: 100%;
  height: 100%;
}
</style>

<template>
  <!-- e-charts 图 -->
  <div
    class="base-charts"
    @mouseover="onMouseOver"
    @mouseout="onMouseOut"
  ></div>
</template>

<script>
import * as ECharts from "echarts";
import { debounce } from "./utils";

export default {
  name: "BaseECharts",
  props: {
    // 配置
    options: {
      type: Object,
      default: () => ({}),
    },
    // 是否开启点击功能
    isClick: {
      type: Boolean,
      default: false,
    },
    // 自动悬停效果
    autoHover: {
      type: Boolean,
      default: () => false,
    },
    // 间隔时间
    intervals: {
      type: Number,
      default: () => 3000,
    },
  },
  data() {
    return {
      // e-charts 图
      chart: null,
      // 当前索引
      mapCurrentIndex: -1,
      // 定时器
      timer: null,
      // 设置
      isSet: false,
    };
  },
  watch: {
    options: {
      deep: true,
      handler(val) {
        if (this.chart) {
          this.chart.setOption(val, true);
          this.mapCurrentIndex = -1;
          this._removeChart();
          this._autoSwitchTooltip();
        }
      },
    },
  },
  mounted() {
    this._initChart();
    this._resizeHandler = debounce(() => {
      if (this.chart) {
        this.chart.resize();
      }
    }, 100);
    window.addEventListener("resize", this._resizeHandler);
  },
  destroyed() {
    this._clearTimer();
    if (!this.chart) {
      return;
    }
    window.removeEventListener("resize", this._resizeHandler);
    this.chart.dispose();
    this.chart = null;
  },
  methods: {
    /**
     * 初始化 e-charts 图
     * @private
     */
    _initChart() {
      this.chart = ECharts.init(this.$el, "macarons");
      this.chart.setOption(this.options, true);
      // 点击
      if (this.isClick) {
        this.chart.on("click", (params) => {
          this.$emit("on-click", params);
        });
      }
      this._autoSwitchTooltip();
    },

    /**
     * 自动切换选中
     * @private
     */
    _autoSwitchTooltip() {
      // 自动切换
      if (this.autoHover) {
        this._clearTimer();
        // 2、鼠标移动上去的时候的高亮动画
        this.chart.on("mouseover", (param) => {
          if (param.seriesType !== "map") {
            this.isSet = false;
            this._clearTimer();
            // 取消之前高亮的图形
            this.chart &&
              this.chart.dispatchAction({
                type: "downplay",
                seriesIndex: 0,
                dataIndex: this.mapCurrentIndex,
              });
            // 高亮当前图形
            this.chart &&
              this.chart.dispatchAction({
                type: "highlight",
                seriesIndex: 0,
                dataIndex: param.dataIndex,
              });
            // 显示 tooltip
            this.chart &&
              this.chart.dispatchAction({
                type: "showTip",
                seriesIndex: 0,
                dataIndex: param.dataIndex,
              });
            this.mapCurrentIndex = param.dataIndex;
          }
        });
        this._chartHover();
        this.timer = setInterval(this._chartHover, this.intervals);
        // 4、鼠标移出之后，恢复自动高亮
        this.chart.on("mouseout", () => {
          if (!this.isSet) {
            this._chartHover();
            this._clearTimer();
            this.timer = setInterval(this._chartHover, this.intervals);
            this.isSet = true;
          }
        });
      }
    },

    /**
     * 移除监听事件
     * @private
     */
    _removeChart() {
      if (this.chart) {
        this.chart.off("mouseover");
        this.chart.off("mouseout");
      }
    },

    /**
     * 清除定时器
     * @private
     */
    _clearTimer() {
      if (this.timer) {
        clearInterval(this.timer);
      }
    },

    /**
     * 图表悬停
     * @private
     */
    _chartHover() {
      let dataLen =
        this.options &&
        this.options.series &&
        this.options.series.length > 0 &&
        this.options.series[0].data &&
        this.options.series[0].data.length;
      if (!dataLen) {
        this._clearTimer();
        this._removeChart();
      }
      // 取消之前高亮的图形
      this.chart &&
        this.chart.dispatchAction({
          type: "downplay",
          seriesIndex: 0,
          dataIndex: this.mapCurrentIndex,
        });
      this.mapCurrentIndex = (this.mapCurrentIndex + 1) % dataLen;
      // 高亮当前图形
      this.chart &&
        this.chart.dispatchAction({
          type: "highlight",
          seriesIndex: 0,
          dataIndex: this.mapCurrentIndex,
        });
      // 显示 tooltip
      this.chart &&
        this.chart.dispatchAction({
          type: "showTip",
          seriesIndex: 0,
          dataIndex: this.mapCurrentIndex,
        });
    },

    /**
     * 鼠标移入
     */
    onMouseOver() {
      this._clearTimer();
    },

    /**
     * 鼠标移除
     */
    onMouseOut() {
      this._autoSwitchTooltip();
    },
  },
};
</script>
